package com.ictest.detectionflow.mobile;

import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

/**
 * 登陆活动。
 * 
 * @author ZengE
 * 
 */
public class LoginActivity extends Activity
{

	/**
	 * 保存键值。
	 */
	public final static String KEY_REMEBER = "authentication_remeber";

	/**
	 * 用户名键值。
	 */
	public final static String KEY_USERNAME = "authentication_username";

	/**
	 * 密码键值。
	 */
	public final static String KEY_PASSWORD = "authentication_password";

	/**
	 * 会话编号。
	 */
	public static String SESSION_ID;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		// 调用基类实现。
		super.onCreate(savedInstanceState);

		// 设置内容视图
		setContentView(R.layout.activity_login);

		// 获得确定按钮
		Button cmdOK = (Button) this.findViewById(R.id.cmdOK);

		// 挂接点击事件
		cmdOK.setOnClickListener(new OnClickListener()
		{
			// 处理点击事件
			public void onClick(View v)
			{
				// 判断是否设定了服务器地址
				if (!Utility.hasServiceAddress(LoginActivity.this))
				{
					// 提示消息
					Utility.notifySetServiceAddress(LoginActivity.this);

					// 返回
					return;
				}

				// 获得用户名输入框
				EditText txtUserName = (EditText) LoginActivity.this.findViewById(R.id.txtUserName);

				// 获得用户名
				String username = txtUserName.getText().toString();

				// 判断是否输入了内容
				if (null == username || username.length() == 0)
				{
					// 提示信息
					Toast.makeText(LoginActivity.this, "请填写用户名。", Toast.LENGTH_SHORT).show();

					// 全部选中
					txtUserName.selectAll();

					// 设置焦点
					txtUserName.requestFocus();

					// 返回
					return;
				}

				// 获得用户名输入框
				EditText txtPassword = (EditText) LoginActivity.this.findViewById(R.id.txtPassword);

				// 获得密码
				String password = txtPassword.getText().toString();

				// 判断是否输入了内容
				if (null == password || password.length() == 0)
				{
					// 提示信息
					Toast.makeText(LoginActivity.this, "请填写登录密码。", Toast.LENGTH_SHORT).show();

					// 全部选中
					txtPassword.selectAll();

					// 设置焦点
					txtPassword.requestFocus();

					// 返回
					return;
				}

				// 创建登陆任务
				LoginActivity.LoginTask task = new LoginActivity.LoginTask();

				// 启用同步任务
				task.execute(username, password);
			}
		});

		// 获得确定按钮
		Button cmdCancel = (Button) this.findViewById(R.id.cmdCancel);

		// 挂接点击事件
		cmdCancel.setOnClickListener(new OnClickListener()
		{
			// 处理点击事件
			public void onClick(View v)
			{
				// 设定返回值
				LoginActivity.this.setResult(Activity.RESULT_CANCELED);

				// 结束活动
				LoginActivity.this.finish();
			}
		});

		// 获得共享存储器
		SharedPreferences settings = getSharedPreferences(getString(R.string.app_name), 0);

		// 获得是否保存用户名设定
		boolean isRemeber = settings.getBoolean(LoginActivity.KEY_REMEBER, false);

		// 获得保存控件
		CheckBox chkRemeber = (CheckBox) this.findViewById(R.id.chkRemeber);

		// 设置选中状态
		chkRemeber.setChecked(isRemeber);

		// 如果记忆，则读取用户名密码
		if (isRemeber)
		{
			// 读取用户名
			String username = settings.getString(LoginActivity.KEY_USERNAME, null);

			// 获得用户名输入框
			EditText txtUserName = (EditText) this.findViewById(R.id.txtUserName);

			// 设置用户名
			txtUserName.setText(username);

			// 读取密码
			String password = settings.getString(LoginActivity.KEY_PASSWORD, null);

			// 获得用户名输入框
			EditText txtPassword = (EditText) this.findViewById(R.id.txtPassword);

			// 设置密码
			txtPassword.setText(password);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		return true;
	}

	@Override
	protected void onDestroy()
	{
		// 调用基类实现
		super.onDestroy();

		// 获得共享存储器
		SharedPreferences settings = getSharedPreferences(getString(R.string.app_name), 0);

		// 开始编辑
		SharedPreferences.Editor editor = settings.edit();

		try
		{
			// 获得保存控件
			CheckBox chkRemeber = (CheckBox) this.findViewById(R.id.chkRemeber);

			// 保存选中状态
			editor.putBoolean(LoginActivity.KEY_REMEBER, chkRemeber.isChecked());

			// 如果记忆，则读取用户名密码
			if (chkRemeber.isChecked())
			{
				// 获得用户名输入框
				EditText txtUserName = (EditText) this.findViewById(R.id.txtUserName);

				// 保存用户名
				editor.putString(LoginActivity.KEY_USERNAME, txtUserName.getText().toString());

				// 获得用户名输入框
				EditText txtPassword = (EditText) this.findViewById(R.id.txtPassword);

				// 保存密码
				editor.putString(LoginActivity.KEY_PASSWORD, txtPassword.getText().toString());
			}
			else
			{
				// 删除用户名
				editor.remove(LoginActivity.KEY_USERNAME);
				// 删除密码
				editor.remove(LoginActivity.KEY_PASSWORD);
			}
		}
		finally
		{
			// 提交数据
			editor.commit();
		}
	}

	/**
	 * 登陆任务。
	 * 
	 * @author zanezeng
	 * 
	 */
	public class LoginTask extends AsyncTask<String, String, JSONObject>
	{
		/**
		 * 进度对话框。
		 */
		private ProgressDialog m_ProgressDialog;

		/**
		 * 登陆过程中发生的错误。
		 */
		private Exception m_InnerException;

		/**
		 * HTTP请求成功编码。
		 */
		private final static int HTTP_OK = 200;

		/**
		 * 连接超时。
		 */
		private final static int CONNECTION_TIMEOUT = 10000;

		/**
		 * 数据接收超时。
		 */
		private final static int SOCKET_TIMEOUT = 30000;

		/**
		 * 数据读取缓存长度。
		 */
		private final static int BUFFER_LENGTH = 1024;

		/**
		 * 日志标记。
		 */
		private final static String LOG_TAG = "LoginTask";

		@Override
		protected void onPreExecute()
		{
			// 创建进度对话框
			this.m_ProgressDialog = new ProgressDialog(LoginActivity.this);
			// 设置进度条样式
			this.m_ProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
			// 设置标题
			this.m_ProgressDialog.setTitle(R.string.title_login);
			// 设置提示信息
			this.m_ProgressDialog.setMessage(LoginActivity.this.getString(R.string.message_login));
			// 设置允许取消
			this.m_ProgressDialog.setCancelable(true);
			// 挂接后退按钮点击事件
			this.m_ProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener()
			{
				// 处理取消按钮点击事件
				public void onCancel(DialogInterface dialog)
				{
					// 取消任务
					LoginTask.this.cancel(true);
				}
			});
			// 设置按钮标题
			this.m_ProgressDialog.setButton(LoginActivity.this.getString(R.string.button_cancel), new DialogInterface.OnClickListener()
			{
				public void onClick(DialogInterface dialog, int which)
				{
					// 取消任务
					LoginTask.this.cancel(true);
				}
			});

			// 设置图标
			this.m_ProgressDialog.setIcon(R.drawable.icon_login);
			// 显示对话框
			this.m_ProgressDialog.show();
		}

		@Override
		protected JSONObject doInBackground(String... params)
		{
			try
			{
				// 创建请求客户端
				DefaultHttpClient client = new DefaultHttpClient();

				// 获得用户名
				String username = params[0];

				// 获得密码
				String password = params[1];

				// 读取数据
				return this.doLogin(client, username, password);
			}
			catch (Exception ex)
			{
				// 记录日志
				Log.e(LoginTask.LOG_TAG, ex.toString());

				// 记录同步过程中发生的异常
				this.m_InnerException = ex;

				// 返回同步失败
				return null;
			}
		}

		@Override
		protected void onProgressUpdate(String... values)
		{
			// 判断进度窗体是否已经创建
			if (null != this.m_ProgressDialog)
			{
				this.m_ProgressDialog.setMessage(values[0]);
			}
		}

		/**
		 * 同步任务后置处理器。
		 */
		@Override
		protected void onPostExecute(JSONObject result)
		{
			// 释放对话框对象
			if (null != this.m_ProgressDialog)
			{
				this.m_ProgressDialog.dismiss();
			}

			// 判断是否发生异常
			if (null != this.m_InnerException)
			{
				// 创建对话框
				AlertDialog.Builder dialog = new AlertDialog.Builder(LoginActivity.this);

				// 设置标题
				dialog.setTitle(R.string.title_application_name);
				// 设置消息
				dialog.setMessage("用户登陆失败，用户登陆的过程中发生错误：\r\n" + this.m_InnerException.toString());
				// 设置不允许取消
				dialog.setCancelable(false);
				// 设置图标编号
				dialog.setIcon(R.drawable.icon_error);

				// 添加取消按钮
				dialog.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener()
				{
					// 处理点击事件
					public void onClick(DialogInterface dialog, int which)
					{
						// 关闭对话框
						dialog.dismiss();
					}
				});

				// 显示对话框
				dialog.show();
			}
			else
			{
				try
				{
					// 判断是否登录成功
					if (!result.getBoolean("IsSuccessed"))
					{
						// 创建对话框
						AlertDialog.Builder dialog = new AlertDialog.Builder(LoginActivity.this);

						// 设置标题
						dialog.setTitle(R.string.title_application_name);
						// 设置消息
						dialog.setMessage(result.getString("ErrorMessage"));
						// 设置不允许取消
						dialog.setCancelable(false);
						// 设置图标编号
						dialog.setIcon(R.drawable.icon_error);

						// 添加取消按钮
						dialog.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener()
						{
							// 处理点击事件
							public void onClick(DialogInterface dialog, int which)
							{
								// 关闭对话框
								dialog.dismiss();
							}
						});

						// 显示对话框
						dialog.show();
					}
					else
					{
						// 提示信息
						Toast.makeText(LoginActivity.this, "用户登录成功。", Toast.LENGTH_SHORT).show();

						// 保存会话编号
						LoginActivity.SESSION_ID = result.getString("SessionID");

						// 设定返回值
						LoginActivity.this.setResult(Activity.RESULT_OK);

						// 结束活动
						LoginActivity.this.finish();
					}
				}
				catch (Exception ex)
				{
					// 创建对话框
					AlertDialog.Builder dialog = new AlertDialog.Builder(LoginActivity.this);

					// 设置标题
					dialog.setTitle(R.string.title_application_name);
					// 设置消息
					dialog.setMessage("用户登陆失败，用户登陆的过程中发生错误：\r\n" + ex.toString());
					// 设置不允许取消
					dialog.setCancelable(false);
					// 设置图标编号
					dialog.setIcon(R.drawable.icon_error);

					// 添加取消按钮
					dialog.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener()
					{
						// 处理点击事件
						public void onClick(DialogInterface dialog, int which)
						{
							// 关闭对话框
							dialog.dismiss();
						}
					});

					// 显示对话框
					dialog.show();
				}
			}
		}

		/**
		 * 执行登陆。
		 */
		private JSONObject doLogin(DefaultHttpClient client, String username, String password) throws Exception
		{
			// 获得共享存储器
			SharedPreferences settings = getSharedPreferences(getString(R.string.app_name), 0);

			// 读取服务器地址
			String url = settings.getString(SettingActivity.KEY_ADDRESS, null);

			// 判断是否以/结尾
			if (url.endsWith("/"))
			{
				url = String.format("%1$sServices/MobileService.svc/Login", url);
			}
			else
			{
				url = String.format("%1$s/Services/MobileService.svc/Login", url);
			}

			// 创建HTTP请求对象
			HttpPost request = new HttpPost(url);

			// 创建条件对象
			JSONObject condition = new JSONObject();

			// 添加条件
			condition.put("username", username);
			condition.put("password", password);

			// 添加条件
			request.setEntity(new StringEntity(condition.toString(), HTTP.UTF_8));

			// 设置参数
			request.setHeader("Accept", "application/json");
			request.setHeader("Content-type", "application/json");

			// 获得请求参数
			HttpParams params = request.getParams();

			// 设置连接超时
			HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
			// 设置接收超时
			HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT);

			// 执行请求
			HttpResponse response = client.execute(request);

			// 读取反馈内容
			String responseText = RetrieveInputStream(response.getEntity());

			// 判断是否请求成功
			if (HTTP_OK != response.getStatusLine().getStatusCode())
			{
				// 记录日志
				Log.e(LOG_TAG, responseText);

				// 抛出异常
				throw new Exception(responseText);
			}

			// 返回数据
			return new JSONObject(responseText);
		}

		/**
		 * 从给定的HTTP实体中获得反馈内容。
		 */
		private String RetrieveInputStream(HttpEntity entity) throws Exception
		{
			// 获得内容长度
			int length = (int) entity.getContentLength();

			// 判断长度是否小于0
			if (length < 0)
			{
				// 如果小于0，则默认为10K
				length = 10 * BUFFER_LENGTH;
			}

			// 用于保存返回字符串内容
			StringBuffer result = new StringBuffer(length);

			// 创建输入流读取器
			InputStreamReader reader = new InputStreamReader(entity.getContent(), HTTP.UTF_8);

			// 用于保存缓存数据
			char buffer[] = new char[BUFFER_LENGTH];

			// 用于记录读取的数据长度
			int count = 0;

			// 循环读取数据
			do
			{
				// 读取数据
				count = reader.read(buffer, 0, BUFFER_LENGTH);

				// 判断是否读取了数据
				if (count > 0)
				{
					// 添加数据
					result.append(buffer, 0, count);
				}
			}
			while (count > 0);

			// 返回结果
			return result.toString();
		}
	}
}
